package com.navidove.web.vo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.displaytag.pagination.PaginatedList;
import org.displaytag.properties.SortOrderEnum;

import com.navidove.commons.vo.Paging;

public class DisplaytagPaging implements Paging {    

    private static final long serialVersionUID = 2219952365020907166L;

    public enum PageSizes {
        TEN(10),TWENTY(20),FORTY(40),SIXTY(60),HUNDRED(100);
        private Integer size;
        private PageSizes(Integer size) {
            this.size = size;
        }
        public Integer getSize() {
            return size;
        }
    }
    
    private static final String ascending = "asc";
    private static final String descending = "desc";
    

    private int objectsPerPage = 15;

    private int page = 1;

    private String sid;

    private String sort;

    private String dir;
    
    private boolean isAsc;
    
    private int fullSize;
    
    public DisplaytagPaging() {
    }

    public int getPage() {
        return this.page;
    }
    public void setPage(int page) {
        this.page = page;
    }
    
    public String getSort() {
        return sort;
    }
    public void setSort(String sort) {
        this.sort = sort;
    }
    public String getDir() {
        return this.dir;
    }
    public void setDir(String dir) {
        this.dir = dir;
        if (dir != null && dir.equals(ascending)) {
            this.dir = "asc";
            isAsc = true;
        } else if (dir != null && dir.equals(descending)) {
            this.dir = "desc";
            isAsc = false;
        }
    }
    public String getSid() {
        return this.sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }

    public int getObjectsPerPage() {
        if (this.objectsPerPage == 0) {
            this.setObjectsPerPage(this.getFullSize());
        }
        return this.objectsPerPage;
    }
    public void setObjectsPerPage(int objectsPerPage) {
        this.objectsPerPage = objectsPerPage;
    }

    public int getFirstResult() {
        return (this.page - 1) * this.objectsPerPage;
    }

    public boolean isAsc() {
		return isAsc;
	}

	public void setAsc(boolean isAsc) {
		this.isAsc = isAsc;
		if (this.isAsc) {
			dir = ascending;
		} else {
			dir = descending;
		}
	}

	/**
     * Create a paginatedList
     *
     * @param list
     * @param fullSize
     * @return
     */
    public PaginatedList createPaginatedList(final List<?> list, final int fullSize) {
        int page = ((fullSize - 1) / DisplaytagPaging.this.getObjectsPerPage()) + 1;
        if (page < this.page) {
            this.page = page;
        }
        return new PaginatedList() {
            public int getFullListSize() {
                return fullSize;
            }

            public List<?> getList() {
                return list;
            }

            public int getObjectsPerPage() {                
                return DisplaytagPaging.this.getObjectsPerPage();
            }

            public int getPageNumber() {
                return DisplaytagPaging.this.page;
            }

            public String getSearchId() {
                return DisplaytagPaging.this.sid;
            }

            public String getSortCriterion() {
                return DisplaytagPaging.this.sort;
            }

            public SortOrderEnum getSortDirection() {
                return DisplaytagPaging.this.isAsc()?SortOrderEnum.ASCENDING: SortOrderEnum.DESCENDING;
            }
        };
    }

    public PaginatedList createPaginatedList(List<?> list) {
        return this.createPaginatedList(list, this.fullSize);
    }

    public int getFullSize() {
        return this.fullSize;
    }
    
    public void setFullSize(int fullSize) {
        this.fullSize = fullSize;
    }
    
    public PageSizes[] getPageSizeList() {
        return PageSizes.values();
    }
    
    public int getTotalPageSize() {
        if (this.getFullSize() == 0) return 0;
        return (int) (this.getFullSize() / this.getObjectsPerPage())  + (this.getFullSize() % this.getObjectsPerPage() > 0 ? 1 : 0);
        
    }
    
    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object rhs) {
        return EqualsBuilder.reflectionEquals(this, rhs);
    }

    /**
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

	/**
	 * @see com.navidove.commons.vo.Paging#getOrder()
	 */
	@Override
	public Map<String, String> getOrder() {
		
		Map<String, String> map = new HashMap<String, String>();
		if (StringUtils.isNotBlank(getSort())) {
			map.put(getSort(), getDir());
		}
		return map;
	}
}
